<template>
    <a-card :loading="loading" :bordered="false" bodyStyle="padding: 0px">
        <template #title>
            <span>道家格言</span>
        </template>
        <div>
            <!-- 格言警句、标签、刷新按钮 -->
            <div class="content">
                <p id="aphorism" class="aphorism">{{ aphorism }}</p>
                <p class="tags">
                    <span v-for="tag in tags">{{ tag }}</span>
                </p>
                <p class="refresh">
                    <a-button :disabled="refreshDisabled" @click="loadAphorism">换一句</a-button>
                </p>
            </div>
            <!-- 人群 -->
            <div class="peoples">
                <canvas id="canvas"></canvas>
            </div>
        </div>
    </a-card>
</template>

<script>
    import {defineComponent, onMounted, reactive, toRefs} from 'vue';
    import gsap from 'gsap';
    import fitty from 'fitty';
    import {getAphorism} from '@/api/aphorism';

    export default defineComponent({
        setup() {
            const state = reactive({
                // 遮罩层
                loading: false,
                // 查询参数
                query: {},
                // 经典格言
                aphorism: '正在努力加载中.....',
                // 标签
                tags: ['加载中'],
                // 换一句按钮禁用
                refreshDisabled: false,
                // 人群画布
                canvas: null,
                // 画布2d对象
                ctx: null,
                // 人群动画
                img: null,
                // 所有人
                allPeoples: [],
                // 可用人
                availablePeoples: [],
                // 人群
                crowd: [],
                // 行走
                walks: [],
                // 状态
                stage: {
                    width: 0,
                    height: 0
                }
            });
            // 查询数据
            const loadAphorism = () => {
                // 按钮禁用
                state.refreshDisabled = true;
                // 请求数据
                getAphorism(state.query).then(response => {
                    // 响应成功
                    if (response.data && response.data.code == 200 && response.data.data) {
                        // 响应数据
                        let data = response.data.data;
                        // 经典格言
                        state.aphorism = data.data.aphorism;
                        // 标签
                        let tags = data.data.tags;
                        // 使用英文逗号分割tag
                        state.tags = tags.split(",");
                        // 按钮启用
                        state.refreshDisabled = false;
                        // 调整文本
                        fitty('#aphorism', {
                            "maxSize": 32
                        });
                    }
                });
            };

            // 定义人像
            class People {
                // 构造方法
                constructor({image, rect}) {
                    this.image = image;
                    this.setRect(rect);
                    this.x = 0;
                    this.y = 0;
                    this.anchorY = 0;
                    this.scaleX = 1;
                    this.walk = null;
                }
                // 设置形状
                setRect(rect) {
                    this.rect = rect;
                    this.width = rect[2] * 0.66;
                    this.height = rect[3] * 0.66;
                    this.drawArgs = [this.image, ...rect, 0, 0, this.width, this.height];
                }
                // 渲染方法
                render(ctx) {
                    ctx.save();
                    ctx.translate(this.x, this.y);
                    ctx.scale(this.scaleX, 1);
                    ctx.drawImage(...this.drawArgs);
                    ctx.restore();
                }
            }
            // 加载人群动画
            const loadPeoples = () => {
                // 获取画布
                state.canvas = document.querySelector('#canvas');
                // 画布2d对象
                state.ctx = state.canvas.getContext('2d');
                // 行走
                state.walks = [normalWalk];
                // 创建图片对象
                state.img = document.createElement('img');
                state.img.src = require("@/assets/aphorism/peoples.png");
                state.img.onload = init();
            };
            // 动画初始化
            const init = () => {
                createPeoples();
                resize();
                gsap.ticker.add(render);
                window.addEventListener('resize', resize);
            };
            // 创建人群
            const createPeoples = () => {
                const rows = 15;
                const cols = 7;
                const {naturalWidth: width, naturalHeight: height} = state.img;
                const total = rows * cols;
                const rectWidth = width / rows;
                const rectHeight = height / cols;
                for (let i = 0; i < total; i++) {
                    state.allPeoples.push(new People({
                        image: state.img,
                        rect: [i % rows * rectWidth, (i / rows | 0) * rectHeight, rectWidth, rectHeight * 0.5]
                    }));
                }
            };
            // 重置大小
            const resize = () => {
                state.stage.width = state.canvas.clientWidth;
                state.stage.height = state.canvas.clientHeight;
                state.canvas.width = state.stage.width * devicePixelRatio;
                state.canvas.height = state.stage.height * devicePixelRatio;
                state.crowd.forEach(people => {
                    people.walk.kill();
                });
                state.crowd.length = 0;
                state.availablePeoples.length = 0;
                state.availablePeoples.push(...state.allPeoples);
                initCrowd();
            };
            // 渲染
            const render = () => {
                state.canvas.width = state.canvas.width;
                state.ctx.save();
                state.ctx.scale(devicePixelRatio, devicePixelRatio);
                state.crowd.forEach(people => {
                    people.render(state.ctx);
                });
                state.ctx.restore();
            };
            // 初始化人群
            const initCrowd = () => {
                while (state.availablePeoples.length) {
                    addPeopleToCrowd().walk.progress(Math.random());
                }
            };
            // 随机人群
            const addPeopleToCrowd = () => {
                const people = removeRandomFromArray(state.availablePeoples);
                const walk = getRandomFromArray(state.walks)({
                    people,
                    props: resetPeople({
                        people: people,
                        stage: state.stage
                    })
                }).eventCallback('onComplete', () => {
                    removePeopleFromCrowd(people);
                    addPeopleToCrowd();
                });
                people.walk = walk;
                state.crowd.push(people);
                state.crowd.sort((a, b) => a.anchorY - b.anchorY);
                return people;
            };
            // 从人群中移除
            const removePeopleFromCrowd = (people) => {
                removeItemFromArray(state.crowd, people);
                state.availablePeoples.push(people);
            };
            // 重置人像
            const resetPeople = ({stage, people}) => {
                const direction = Math.random() > 0.5 ? 1 : -1;
                // using an ease function to skew random to lower values to help hide that peeps have no legs
                const offsetY = 80 - 160 * gsap.parseEase('power2.in')(Math.random());
                const startY = stage.height - people.height + offsetY;
                let startX = 0;
                let endX = 0;
                if (direction === 1) {
                    startX = -people.width;
                    endX = stage.width;
                    people.scaleX = 1;
                } else {
                    startX = stage.width + people.width;
                    endX = 0;
                    people.scaleX = -1;
                }
                people.x = startX;
                people.y = startY;
                people.anchorY = startY;
                return {startX, startY, endX};
            };
            // 人像行走
            const normalWalk = ({people, props}) => {
                const {startX, startY, endX} = props;
                const xDuration = 10;
                const yDuration = 0.25;
                const tl = gsap.timeline();
                tl.timeScale(randomRange(0.2, 1.2));
                tl.to(people, {
                    duration: xDuration,
                    x: endX,
                    ease: 'none'
                }, 0);
                tl.to(people, {
                    duration: yDuration,
                    repeat: xDuration / yDuration,
                    yoyo: true,
                    y: startY - 10
                }, 0);
                return tl;
            };
            // 获取范围内随机值
            const randomRange = (min, max) => {
                return min + Math.random() * (max - min);
            };
            // 获取数组随机索引
            const randomIndex = (array) => {
                return randomRange(0, array.length) | 0;
            };
            // 数组移除元素
            const removeFromArray = (array, i) => {
                return array.splice(i, 1)[0];
            };
            // 数组移除元素
            const removeItemFromArray = (array, item) => {
                return removeFromArray(array, array.indexOf(item));
            };
            // 数组移除随机元素
            const removeRandomFromArray = (array) => {
                return removeFromArray(array, randomIndex(array));
            };
            // 获取数组随机元素
            const getRandomFromArray = (array) => {
                return array[randomIndex(array) | 0];
            };

            // 加载页面
            onMounted(() => {
                // 加载动画
                loadPeoples();
                // 加载数据
                loadAphorism();
            });

            return {
                ...toRefs(state),
                loadAphorism
            };
        }
    });
</script>

<style scoped>
    /* 内容区 */
    .content {
        width: 80%;
        margin: 0 auto;
        padding-top: 16%;
        text-align: center;
    }

    /* 经典格言 */
    .content .aphorism {
        height: 3.2rem;
        font-size: 1.6rem;
        margin: 0;
    }

    /* 标签集合 */
    .content .tags {
        margin-top: 0.6rem;
    }

    /* 标签 */
    .content .tags span {
        margin: 0 0.3rem;
        padding: 0 0.4rem 0.1rem 0.4rem;
        border: 0.05rem solid #666666;
        border-radius: 0.98rem;
        color: #666666;
        font-size: 0.68rem;
    }

    /* 换一句按钮 */
    .refresh {
        margin-top: 1.6rem;
    }

    .refresh button {
        z-index: 999;
        height: 1.6rem;
        width: 8rem;
        border: 0.1rem solid #666666;
        border-radius: 0.4rem;
        color: #666666;
        font-weight: bold;
        font-size: 0.6rem;
        line-height: 1;
        letter-spacing: 0.05rem;
    }

    /* 人群区域样式 */
    .peoples {
        display: flex;
        width: 100%;
        align-items: center;
    }

    /* 画布尺寸 */
    #canvas {
        height: 100%;
        width: 100%;
    }
</style>
